#include "gtkliststore.h"
#include "gtktreedatalist.h"
#include "gtktreednd.h"
-#include "gtksequence.h"
#include "gtkintl.h"
#include "gtkalias.h"
#define GTK_LIST_STORE_IS_SORTED(list) (((GtkListStore*)(list))->sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
-#define VALID_ITER(iter, list_store) ((iter)!= NULL && (iter)->user_data != NULL && list_store->stamp == (iter)->stamp && !_gtk_sequence_ptr_is_end ((iter)->user_data) && _gtk_sequence_ptr_get_sequence ((iter)->user_data) == list_store->seq)
+#define VALID_ITER(iter, list_store) ((iter)!= NULL && (iter)->user_data != NULL && list_store->stamp == (iter)->stamp && !g_sequence_iter_is_end ((iter)->user_data) && g_sequence_iter_get_sequence ((iter)->user_data) == list_store->seq)
static void gtk_list_store_tree_model_init (GtkTreeModelIface *iface);
static void gtk_list_store_drag_source_init(GtkTreeDragSourceIface *iface);
static void
gtk_list_store_init (GtkListStore *list_store)
{
- list_store->seq = _gtk_sequence_new (NULL);
+ list_store->seq = g_sequence_new (NULL);
list_store->sort_list = NULL;
list_store->stamp = g_random_int ();
list_store->sort_column_id = -2;
g_return_if_fail (list_store->columns_dirty == 0);
gtk_list_store_set_n_columns (list_store, n_columns);
- for (i = 0; i < n_columns; i++)
+ for (i = 0; i < n_columns; i++)
{
if (! _gtk_tree_data_list_check_type (types[i]))
{
{
GtkListStore *list_store = GTK_LIST_STORE (object);
- _gtk_sequence_foreach (list_store->seq,
- (GFunc) _gtk_tree_data_list_free, list_store->column_headers);
+ g_sequence_foreach (list_store->seq,
+ (GFunc) _gtk_tree_data_list_free, list_store->column_headers);
- _gtk_sequence_free (list_store->seq);
+ g_sequence_free (list_store->seq);
_gtk_tree_data_list_header_free (list_store->sort_list);
g_free (list_store->column_headers);
GtkTreePath *path)
{
GtkListStore *list_store = (GtkListStore *) tree_model;
- GtkSequence *seq;
+ GSequence *seq;
gint i;
list_store->columns_dirty = TRUE;
i = gtk_tree_path_get_indices (path)[0];
- if (i >= _gtk_sequence_get_length (seq))
+ if (i >= g_sequence_get_length (seq))
return FALSE;
iter->stamp = list_store->stamp;
- iter->user_data = _gtk_sequence_get_ptr_at_pos (seq, i);
+ iter->user_data = g_sequence_get_iter_at_pos (seq, i);
return TRUE;
}
g_return_val_if_fail (iter->stamp == GTK_LIST_STORE (tree_model)->stamp, NULL);
- if (_gtk_sequence_ptr_is_end (iter->user_data))
+ if (g_sequence_iter_is_end (iter->user_data))
return NULL;
path = gtk_tree_path_new ();
- gtk_tree_path_append_index (path, _gtk_sequence_ptr_get_position (iter->user_data));
+ gtk_tree_path_append_index (path, g_sequence_iter_get_position (iter->user_data));
return path;
}
g_return_if_fail (column < list_store->n_columns);
g_return_if_fail (VALID_ITER (iter, list_store));
- list = _gtk_sequence_ptr_get_data (iter->user_data);
+ list = g_sequence_get (iter->user_data);
while (tmp_column-- > 0 && list)
list = list->next;
GtkTreeIter *iter)
{
g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE);
- iter->user_data = _gtk_sequence_ptr_next (iter->user_data);
+ iter->user_data = g_sequence_iter_next (iter->user_data);
- return !_gtk_sequence_ptr_is_end (iter->user_data);
+ return !g_sequence_iter_is_end (iter->user_data);
}
static gboolean
if (parent)
return FALSE;
- if (_gtk_sequence_get_length (list_store->seq) > 0)
+ if (g_sequence_get_length (list_store->seq) > 0)
{
iter->stamp = list_store->stamp;
- iter->user_data = _gtk_sequence_get_begin_ptr (list_store->seq);
+ iter->user_data = g_sequence_get_begin_iter (list_store->seq);
return TRUE;
}
else
GtkListStore *list_store = (GtkListStore *) tree_model;
if (iter == NULL)
- return _gtk_sequence_get_length (list_store->seq);
+ return g_sequence_get_length (list_store->seq);
g_return_val_if_fail (list_store->stamp == iter->stamp, -1);
gint n)
{
GtkListStore *list_store = (GtkListStore *) tree_model;
- GtkSequencePtr child;
+ GSequenceIter *child;
if (parent)
return FALSE;
- child = _gtk_sequence_get_ptr_at_pos (list_store->seq, n);
+ child = g_sequence_get_iter_at_pos (list_store->seq, n);
- if (_gtk_sequence_ptr_is_end (child))
+ if (g_sequence_iter_is_end (child))
return FALSE;
iter->stamp = list_store->stamp;
converted = TRUE;
}
- prev = list = _gtk_sequence_ptr_get_data (iter->user_data);
+ prev = list = g_sequence_get (iter->user_data);
while (list != NULL)
{
list = list->next;
}
- if (_gtk_sequence_ptr_get_data (iter->user_data) == NULL)
+ if (g_sequence_get (iter->user_data) == NULL)
{
list = _gtk_tree_data_list_alloc();
- _gtk_sequence_set (iter->user_data, list);
+ g_sequence_set (iter->user_data, list);
list->next = NULL;
}
else
GtkTreeIter *iter)
{
GtkTreePath *path;
- GtkSequencePtr ptr, next;
+ GSequenceIter *ptr, *next;
g_return_val_if_fail (GTK_IS_LIST_STORE (list_store), FALSE);
g_return_val_if_fail (VALID_ITER (iter, list_store), FALSE);
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
ptr = iter->user_data;
- next = _gtk_sequence_ptr_next (ptr);
+ next = g_sequence_iter_next (ptr);
- _gtk_tree_data_list_free (_gtk_sequence_ptr_get_data (ptr), list_store->column_headers);
- _gtk_sequence_remove (iter->user_data);
+ _gtk_tree_data_list_free (g_sequence_get (ptr), list_store->column_headers);
+ g_sequence_remove (iter->user_data);
list_store->length--;
gtk_tree_model_row_deleted (GTK_TREE_MODEL (list_store), path);
gtk_tree_path_free (path);
- if (_gtk_sequence_ptr_is_end (next))
+ if (g_sequence_iter_is_end (next))
{
iter->stamp = 0;
return FALSE;
gint position)
{
GtkTreePath *path;
- GtkSequence *seq;
- GtkSequencePtr ptr;
+ GSequence *seq;
+ GSequenceIter *ptr;
gint length;
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
seq = list_store->seq;
- length = _gtk_sequence_get_length (seq);
+ length = g_sequence_get_length (seq);
if (position > length)
position = length;
- ptr = _gtk_sequence_get_ptr_at_pos (seq, position);
- ptr = _gtk_sequence_insert (ptr, NULL);
+ ptr = g_sequence_get_iter_at_pos (seq, position);
+ ptr = g_sequence_insert_before (ptr, NULL);
iter->stamp = list_store->stamp;
iter->user_data = ptr;
GtkTreeIter *iter,
GtkTreeIter *sibling)
{
- GtkSequencePtr after;
+ GSequenceIter *after;
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL);
g_return_if_fail (VALID_ITER (sibling, list_store));
if (!sibling)
- after = _gtk_sequence_get_end_ptr (list_store->seq);
+ after = g_sequence_get_end_iter (list_store->seq);
else
after = sibling->user_data;
- gtk_list_store_insert (list_store, iter, _gtk_sequence_ptr_get_position (after));
+ gtk_list_store_insert (list_store, iter, g_sequence_iter_get_position (after));
}
/**
GtkTreeIter *iter,
GtkTreeIter *sibling)
{
- GtkSequencePtr after;
+ GSequenceIter *after;
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL);
g_return_if_fail (VALID_ITER (sibling, list_store));
if (!sibling)
- after = _gtk_sequence_get_begin_ptr (list_store->seq);
+ after = g_sequence_get_begin_iter (list_store->seq);
else
- after = _gtk_sequence_ptr_next (sibling->user_data);
+ after = g_sequence_iter_next (sibling->user_data);
- gtk_list_store_insert (list_store, iter, _gtk_sequence_ptr_get_position (after));
+ gtk_list_store_insert (list_store, iter, g_sequence_iter_get_position (after));
}
/**
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL);
- gtk_list_store_insert (list_store, iter, _gtk_sequence_get_length (list_store->seq));
+ gtk_list_store_insert (list_store, iter, g_sequence_get_length (list_store->seq));
}
static void
GtkTreeIter iter;
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
- while (_gtk_sequence_get_length (list_store->seq) > 0)
+ while (g_sequence_get_length (list_store->seq) > 0)
{
iter.stamp = list_store->stamp;
- iter.user_data = _gtk_sequence_get_begin_ptr (list_store->seq);
+ iter.user_data = g_sequence_get_begin_iter (list_store->seq);
gtk_list_store_remove (list_store, &iter);
}
if (!VALID_ITER (iter, list_store))
return FALSE;
- if (_gtk_sequence_ptr_get_sequence (iter->user_data) != list_store->seq)
+ if (g_sequence_iter_get_sequence (iter->user_data) != list_store->seq)
return FALSE;
return TRUE;
*/
if (retval)
{
- GtkTreeDataList *dl = _gtk_sequence_ptr_get_data (src_iter.user_data);
+ GtkTreeDataList *dl = g_sequence_get (src_iter.user_data);
GtkTreeDataList *copy_head = NULL;
GtkTreeDataList *copy_prev = NULL;
GtkTreeDataList *copy_iter = NULL;
}
dest_iter.stamp = list_store->stamp;
- _gtk_sequence_set (dest_iter.user_data, copy_head);
+ g_sequence_set (dest_iter.user_data, copy_head);
path = gtk_list_store_get_path (tree_model, &dest_iter);
gtk_tree_model_row_changed (tree_model, path, &dest_iter);
indices = gtk_tree_path_get_indices (dest_path);
- if (indices[0] <= _gtk_sequence_get_length (GTK_LIST_STORE (drag_dest)->seq))
+ if (indices[0] <= g_sequence_get_length (GTK_LIST_STORE (drag_dest)->seq))
retval = TRUE;
out:
gint i;
GtkTreePath *path;
GHashTable *new_positions;
- GtkSequencePtr ptr;
+ GSequenceIter *ptr;
gint *order;
g_return_if_fail (GTK_IS_LIST_STORE (store));
g_return_if_fail (!GTK_LIST_STORE_IS_SORTED (store));
g_return_if_fail (new_order != NULL);
- order = g_new (gint, _gtk_sequence_get_length (store->seq));
- for (i = 0; i < _gtk_sequence_get_length (store->seq); i++)
+ order = g_new (gint, g_sequence_get_length (store->seq));
+ for (i = 0; i < g_sequence_get_length (store->seq); i++)
order[new_order[i]] = i;
new_positions = g_hash_table_new (g_direct_hash, g_direct_equal);
- ptr = _gtk_sequence_get_begin_ptr (store->seq);
+ ptr = g_sequence_get_begin_iter (store->seq);
i = 0;
- while (!_gtk_sequence_ptr_is_end (ptr))
+ while (!g_sequence_iter_is_end (ptr))
{
g_hash_table_insert (new_positions, ptr, GINT_TO_POINTER (order[i++]));
- ptr = _gtk_sequence_ptr_next (ptr);
+ ptr = g_sequence_iter_next (ptr);
}
g_free (order);
- _gtk_sequence_sort (store->seq, gtk_list_store_reorder_func, new_positions);
+ g_sequence_sort_iter (store->seq, gtk_list_store_reorder_func, new_positions);
g_hash_table_destroy (new_positions);
}
static GHashTable *
-save_positions (GtkSequence *seq)
+save_positions (GSequence *seq)
{
GHashTable *positions = g_hash_table_new (g_direct_hash, g_direct_equal);
- GtkSequencePtr ptr;
+ GSequenceIter *ptr;
- ptr = _gtk_sequence_get_begin_ptr (seq);
- while (!_gtk_sequence_ptr_is_end (ptr))
+ ptr = g_sequence_get_begin_iter (seq);
+ while (!g_sequence_iter_is_end (ptr))
{
g_hash_table_insert (positions, ptr,
- GINT_TO_POINTER (_gtk_sequence_ptr_get_position (ptr)));
- ptr = _gtk_sequence_ptr_next (ptr);
+ GINT_TO_POINTER (g_sequence_iter_get_position (ptr)));
+ ptr = g_sequence_iter_next (ptr);
}
return positions;
}
static int *
-generate_order (GtkSequence *seq,
+generate_order (GSequence *seq,
GHashTable *old_positions)
{
- GtkSequencePtr ptr;
- int *order = g_new (int, _gtk_sequence_get_length (seq));
+ GSequenceIter *ptr;
+ int *order = g_new (int, g_sequence_get_length (seq));
int i;
i = 0;
- ptr = _gtk_sequence_get_begin_ptr (seq);
- while (!_gtk_sequence_ptr_is_end (ptr))
+ ptr = g_sequence_get_begin_iter (seq);
+ while (!g_sequence_iter_is_end (ptr))
{
int old_pos = GPOINTER_TO_INT (g_hash_table_lookup (old_positions, ptr));
order[i++] = old_pos;
- ptr = _gtk_sequence_ptr_next (ptr);
+ ptr = g_sequence_iter_next (ptr);
}
g_hash_table_destroy (old_positions);
old_positions = save_positions (store->seq);
- _gtk_sequence_swap (a->user_data, b->user_data);
+ g_sequence_swap (a->user_data, b->user_data);
order = generate_order (store->seq, old_positions);
path = gtk_tree_path_new ();
old_positions = save_positions (store->seq);
- _gtk_sequence_move (iter->user_data, _gtk_sequence_get_ptr_at_pos (store->seq, new_pos));
+ g_sequence_move (iter->user_data, g_sequence_get_iter_at_pos (store->seq, new_pos));
order = generate_order (store->seq, old_positions);
g_return_if_fail (VALID_ITER (position, store));
if (position)
- pos = _gtk_sequence_ptr_get_position (position->user_data);
+ pos = g_sequence_iter_get_position (position->user_data);
else
pos = -1;
g_return_if_fail (VALID_ITER (position, store));
if (position)
- pos = _gtk_sequence_ptr_get_position (position->user_data) + 1;
+ pos = g_sequence_iter_get_position (position->user_data) + 1;
else
pos = 0;
GHashTable *old_positions;
if (!GTK_LIST_STORE_IS_SORTED (list_store) ||
- _gtk_sequence_get_length (list_store->seq) <= 1)
+ g_sequence_get_length (list_store->seq) <= 1)
return;
old_positions = save_positions (list_store->seq);
- _gtk_sequence_sort (list_store->seq, gtk_list_store_compare_func, list_store);
+ g_sequence_sort_iter (list_store->seq, gtk_list_store_compare_func, list_store);
/* Let the world know about our new order */
new_order = generate_order (list_store->seq, old_positions);
iter_is_sorted (GtkListStore *list_store,
GtkTreeIter *iter)
{
- GtkSequencePtr cmp;
+ GSequenceIter *cmp;
- if (!_gtk_sequence_ptr_is_begin (iter->user_data))
+ if (!g_sequence_iter_is_begin (iter->user_data))
{
- cmp = _gtk_sequence_ptr_prev (iter->user_data);
+ cmp = g_sequence_iter_prev (iter->user_data);
if (gtk_list_store_compare_func (cmp, iter->user_data, list_store) > 0)
return FALSE;
}
- cmp = _gtk_sequence_ptr_next (iter->user_data);
- if (!_gtk_sequence_ptr_is_end (cmp))
+ cmp = g_sequence_iter_next (iter->user_data);
+ if (!g_sequence_iter_is_end (cmp))
{
if (gtk_list_store_compare_func (iter->user_data, cmp, list_store) > 0)
return FALSE;
gint *order;
old_positions = save_positions (list_store->seq);
- _gtk_sequence_sort_changed (iter->user_data,
- gtk_list_store_compare_func,
- list_store);
+ g_sequence_sort_changed_iter (iter->user_data,
+ gtk_list_store_compare_func,
+ list_store);
order = generate_order (list_store->seq, old_positions);
path = gtk_tree_path_new ();
gtk_tree_model_rows_reordered (GTK_TREE_MODEL (list_store),
...)
{
GtkTreePath *path;
- GtkSequence *seq;
- GtkSequencePtr ptr;
+ GSequence *seq;
+ GSequenceIter *ptr;
GtkTreeIter tmp_iter;
gint length;
gboolean changed = FALSE;
seq = list_store->seq;
- length = _gtk_sequence_get_length (seq);
+ length = g_sequence_get_length (seq);
if (position > length)
position = length;
- ptr = _gtk_sequence_get_ptr_at_pos (seq, position);
- ptr = _gtk_sequence_insert (ptr, NULL);
+ ptr = g_sequence_get_iter_at_pos (seq, position);
+ ptr = g_sequence_insert_before (ptr, NULL);
iter->stamp = list_store->stamp;
iter->user_data = ptr;
/* Don't emit rows_reordered here */
if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store))
- _gtk_sequence_sort_changed (iter->user_data,
- gtk_list_store_compare_func,
- list_store);
+ g_sequence_sort_changed_iter (iter->user_data,
+ gtk_list_store_compare_func,
+ list_store);
/* Just emit row_inserted */
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
gint n_values)
{
GtkTreePath *path;
- GtkSequence *seq;
- GtkSequencePtr ptr;
+ GSequence *seq;
+ GSequenceIter *ptr;
GtkTreeIter tmp_iter;
gint length;
gboolean changed = FALSE;
seq = list_store->seq;
- length = _gtk_sequence_get_length (seq);
+ length = g_sequence_get_length (seq);
if (position > length)
position = length;
- ptr = _gtk_sequence_get_ptr_at_pos (seq, position);
- ptr = _gtk_sequence_insert (ptr, NULL);
+ ptr = g_sequence_get_iter_at_pos (seq, position);
+ ptr = g_sequence_insert_before (ptr, NULL);
iter->stamp = list_store->stamp;
iter->user_data = ptr;
/* Don't emit rows_reordered here */
if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store))
- _gtk_sequence_sort_changed (iter->user_data,
- gtk_list_store_compare_func,
- list_store);
+ g_sequence_sort_changed_iter (iter->user_data,
+ gtk_list_store_compare_func,
+ list_store);
/* Just emit row_inserted */
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
+++ /dev/null
-/* GLIB - Library of useful routines for C programming
- * Copyright (C) 2002 Soeren Sandmann (sandmann@daimi.au.dk)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <glib.h>
-
-#include "gtksequence.h"
-#include "gtkalias.h"
-
-typedef struct _GtkSequenceNode GtkSequenceNode;
-
-struct _GtkSequence {
- GtkSequenceNode *node; /* does not necessarily point to the root.
- * You can splay it if you want it to
- */
- GDestroyNotify data_destroy_notify;
-};
-
-struct _GtkSequenceNode {
- guint is_end : 1;
- gint n_nodes : 31; /* number of nodes below this node,
- * including this node
- */
- GtkSequenceNode *parent;
- GtkSequenceNode *left;
- GtkSequenceNode *right;
-
- GtkSequence *sequence;
-
- gpointer data;
-};
-
-static GtkSequenceNode *_gtk_sequence_node_new (gpointer data);
-static GtkSequenceNode *_gtk_sequence_node_find_first (GtkSequenceNode *node);
-static GtkSequenceNode *_gtk_sequence_node_find_last (GtkSequenceNode *node);
-static GtkSequenceNode *_gtk_sequence_node_find_by_pos (GtkSequenceNode *node,
- gint pos);
-static GtkSequenceNode *_gtk_sequence_node_prev (GtkSequenceNode *node);
-static GtkSequenceNode *_gtk_sequence_node_next (GtkSequenceNode *node);
-static gint _gtk_sequence_node_get_pos (GtkSequenceNode *node);
-static GtkSequence *_gtk_sequence_node_get_sequence (GtkSequenceNode *node);
-static GtkSequenceNode *_gtk_sequence_node_find_closest (GtkSequenceNode *node,
- GtkSequenceNode *other,
- GCompareDataFunc cmp,
- gpointer data);
-static gint _gtk_sequence_node_get_length (GtkSequenceNode *node);
-static void _gtk_sequence_node_free (GtkSequenceNode *node,
- GDestroyNotify destroy);
-#if 0
-static gboolean _gtk_sequence_node_is_singleton (GtkSequenceNode *node);
-#endif
-static void _gtk_sequence_node_split (GtkSequenceNode *node,
- GtkSequenceNode **left,
- GtkSequenceNode **right);
-static void _gtk_sequence_node_insert_before (GtkSequenceNode *node,
- GtkSequenceNode *new);
-static void _gtk_sequence_node_remove (GtkSequenceNode *node);
-static void _gtk_sequence_node_insert_sorted (GtkSequenceNode *node,
- GtkSequenceNode *new,
- GCompareDataFunc cmp_func,
- gpointer cmp_data);
-
-/* GtkSequence */
-GtkSequence *
-_gtk_sequence_new (GDestroyNotify data_destroy)
-{
- GtkSequence *seq = g_new (GtkSequence, 1);
- seq->data_destroy_notify = data_destroy;
-
- seq->node = _gtk_sequence_node_new (NULL);
- seq->node->is_end = TRUE;
- seq->node->sequence = seq;
-
- return seq;
-}
-
-void
-_gtk_sequence_foreach (GtkSequence *seq,
- GFunc func,
- gpointer data)
-{
- GtkSequencePtr ptr;
-
- g_return_if_fail (seq != NULL);
- g_return_if_fail (func != NULL);
-
- ptr = _gtk_sequence_get_begin_ptr (seq);
-
- while (!_gtk_sequence_ptr_is_end (ptr))
- {
- GtkSequenceNode *node = ptr;
-
- func (node->data, data);
-
- ptr = _gtk_sequence_ptr_next (ptr);
- }
-
-}
-
-void
-_gtk_sequence_free (GtkSequence *seq)
-{
- g_return_if_fail (seq != NULL);
-
- _gtk_sequence_node_free (seq->node, seq->data_destroy_notify);
-
- g_free (seq);
-}
-
-#if 0
-static void
-flatten_nodes (GtkSequenceNode *node, GList **list)
-{
- g_print ("flatten %p\n", node);
- if (!node)
- return;
- else if (_gtk_sequence_node_is_singleton (node))
- *list = g_list_prepend (*list, node);
- else
- {
- GtkSequenceNode *left;
- GtkSequenceNode *right;
-
- _gtk_sequence_node_split (node, &left, &right);
-
- flatten_nodes (left, list);
- flatten_nodes (right, list);
- }
-}
-#endif
-
-typedef struct SortInfo SortInfo;
-struct SortInfo {
- GCompareDataFunc cmp;
- gpointer data;
-};
-
-static gint
-node_compare (gconstpointer n1, gconstpointer n2, gpointer data)
-{
- const SortInfo *info = data;
- const GtkSequenceNode *node1 = n1;
- const GtkSequenceNode *node2 = n2;
- gint retval;
-
- if (node1->is_end)
- return 1;
-
- if (node2->is_end)
- return -1;
-
- retval = (* info->cmp) (node1, node2, info->data);
-
- /* If the nodes are different, but the user-supplied compare function
- * compares them equal, then force an arbitrary (but consistent) order
- * on them, so that our sorts will be stable
- */
- if (retval != 0 || n1 == n2)
- return retval;
-
- if (n1 > n2)
- return 1;
- else
- return -1;
-}
-
-void
-_gtk_sequence_append (GtkSequence *seq,
- gpointer data)
-{
- GtkSequenceNode *node, *last;
-
- g_return_if_fail (seq != NULL);
-
- node = _gtk_sequence_node_new (data);
- node->sequence = seq;
- last = _gtk_sequence_node_find_last (seq->node);
- _gtk_sequence_node_insert_before (last, node);
-}
-#if 0
-
-void
-_gtk_sequence_prepend (GtkSequence *seq,
- gpointer data)
-{
- GtkSequenceNode *node, *second;
-
- g_return_if_fail (seq != NULL);
-
- node = _gtk_sequence_node_new (data);
- node->sequence = seq;
- second = _gtk_sequence_node_next (_gtk_sequence_node_find_first (seq->node));
-
- _gtk_sequence_node_insert_before (second, node);
-}
-#endif
-
-GtkSequencePtr
-_gtk_sequence_insert (GtkSequencePtr ptr,
- gpointer data)
-{
- GtkSequenceNode *node;
-
- g_return_val_if_fail (ptr != NULL, NULL);
-
- node = _gtk_sequence_node_new (data);
- node->sequence = ptr->sequence;
-
- _gtk_sequence_node_insert_before (ptr, node);
-
- return node;
-}
-
-static void
-_gtk_sequence_unlink (GtkSequence *seq,
- GtkSequenceNode *node)
-{
- g_assert (!node->is_end);
-
- seq->node = _gtk_sequence_node_next (node);
-
- g_assert (seq->node);
- g_assert (seq->node != node);
-
- _gtk_sequence_node_remove (node);
-}
-
-void
-_gtk_sequence_remove (GtkSequencePtr ptr)
-{
- GtkSequence *seq;
-
- g_return_if_fail (ptr != NULL);
- g_return_if_fail (!ptr->is_end);
-
- seq = _gtk_sequence_node_get_sequence (ptr);
- _gtk_sequence_unlink (seq, ptr);
- _gtk_sequence_node_free (ptr, seq->data_destroy_notify);
-}
-
-void
-_gtk_sequence_sort (GtkSequence *seq,
- GCompareDataFunc cmp_func,
- gpointer cmp_data)
-{
- GtkSequence *tmp;
- GtkSequenceNode *begin, *end;
-
- g_return_if_fail (seq != NULL);
- g_return_if_fail (cmp_func != NULL);
-
- begin = _gtk_sequence_get_begin_ptr (seq);
- end = _gtk_sequence_get_end_ptr (seq);
-
- _gtk_sequence_remove_range (begin, end, &tmp);
-
- while (_gtk_sequence_get_length (tmp) > 0)
- {
- GtkSequenceNode *node = _gtk_sequence_get_begin_ptr (tmp);
- _gtk_sequence_unlink (tmp, node);
-
- _gtk_sequence_node_insert_sorted (seq->node, node, cmp_func, cmp_data);
- }
-
- _gtk_sequence_free (tmp);
-}
-
-gpointer
-_gtk_sequence_ptr_get_data (GtkSequencePtr ptr)
-{
- g_return_val_if_fail (ptr != NULL, NULL);
- g_return_val_if_fail (!ptr->is_end, NULL);
-
- return ptr->data;
-}
-
-GtkSequencePtr
-_gtk_sequence_insert_sorted (GtkSequence *seq,
- gpointer data,
- GCompareDataFunc cmp_func,
- gpointer cmp_data)
-{
- GtkSequenceNode *new_node = _gtk_sequence_node_new (data);
- new_node->sequence = seq;
- _gtk_sequence_node_insert_sorted (seq->node, new_node, cmp_func, cmp_data);
- return new_node;
-}
-
-void
-_gtk_sequence_insert_sequence (GtkSequencePtr ptr,
- GtkSequence *other_seq)
-{
- GtkSequenceNode *last;
-
- g_return_if_fail (other_seq != NULL);
- g_return_if_fail (ptr != NULL);
-
- last = _gtk_sequence_node_find_last (other_seq->node);
- _gtk_sequence_node_insert_before (ptr, last);
- _gtk_sequence_node_remove (last);
- _gtk_sequence_node_free (last, NULL);
- other_seq->node = NULL;
- _gtk_sequence_free (other_seq);
-}
-
-void
-_gtk_sequence_concatenate (GtkSequence *seq1,
- GtkSequence *seq2)
-{
- GtkSequenceNode *last;
-
- g_return_if_fail (seq1 != NULL);
- g_return_if_fail (seq2 != NULL);
-
- last = _gtk_sequence_node_find_last (seq1->node);
- _gtk_sequence_insert_sequence (last, seq2);
-}
-
-/*
- * The new sequence inherits the destroy notify from the sequence that
- * beign and end comes from
- */
-void
-_gtk_sequence_remove_range (GtkSequencePtr begin,
- GtkSequencePtr end,
- GtkSequence **removed)
-{
- GtkSequence *seq;
- GtkSequenceNode *s1, *s2, *s3;
-
- seq = _gtk_sequence_node_get_sequence (begin);
-
- g_assert (end != NULL);
-
- g_return_if_fail (seq == _gtk_sequence_node_get_sequence (end));
-
- _gtk_sequence_node_split (begin, &s1, &s2);
- _gtk_sequence_node_split (end, NULL, &s3);
-
- if (s1)
- _gtk_sequence_node_insert_before (s3, s1);
-
- seq->node = s3;
-
- if (removed)
- {
- *removed = _gtk_sequence_new (seq->data_destroy_notify);
- _gtk_sequence_node_insert_before ((*removed)->node, s2);
- }
- else
- {
- _gtk_sequence_node_free (s2, seq->data_destroy_notify);
- }
-}
-
-gint
-_gtk_sequence_get_length (GtkSequence *seq)
-{
- return _gtk_sequence_node_get_length (seq->node) - 1;
-}
-
-GtkSequencePtr
-_gtk_sequence_get_end_ptr (GtkSequence *seq)
-{
- g_return_val_if_fail (seq != NULL, NULL);
- return _gtk_sequence_node_find_last (seq->node);
-}
-
-GtkSequencePtr
-_gtk_sequence_get_begin_ptr (GtkSequence *seq)
-{
- g_return_val_if_fail (seq != NULL, NULL);
- return _gtk_sequence_node_find_first (seq->node);
-}
-
-/*
- * if pos > number of items or -1, will return end pointer
- */
-GtkSequencePtr
-_gtk_sequence_get_ptr_at_pos (GtkSequence *seq,
- gint pos)
-{
- gint len;
-
- g_return_val_if_fail (seq != NULL, NULL);
-
- len = _gtk_sequence_get_length (seq);
-
- if (pos > len || pos == -1)
- pos = len;
-
- return _gtk_sequence_node_find_by_pos (seq->node, pos);
-}
-
-
-/* GtkSequencePtr */
-gboolean
-_gtk_sequence_ptr_is_end (GtkSequencePtr ptr)
-{
- g_return_val_if_fail (ptr != NULL, FALSE);
- return ptr->is_end;
-}
-
-gboolean
-_gtk_sequence_ptr_is_begin (GtkSequencePtr ptr)
-{
- return (_gtk_sequence_node_prev (ptr) == ptr);
-}
-
-/* If you call this on an end pointer you'll get
- * the length of the sequence
- */
-gint
-_gtk_sequence_ptr_get_position (GtkSequencePtr ptr)
-{
- g_return_val_if_fail (ptr != NULL, -1);
-
- return _gtk_sequence_node_get_pos (ptr);
-}
-
-GtkSequencePtr
-_gtk_sequence_ptr_next (GtkSequencePtr ptr)
-{
- g_return_val_if_fail (ptr != NULL, NULL);
-
- return _gtk_sequence_node_next (ptr);
-}
-
-GtkSequencePtr
-_gtk_sequence_ptr_prev (GtkSequencePtr ptr)
-{
- g_return_val_if_fail (ptr != NULL, NULL);
-
- return _gtk_sequence_node_prev (ptr);
-}
-
-GtkSequencePtr
-_gtk_sequence_ptr_move (GtkSequencePtr ptr,
- guint delta)
-{
- gint new_pos;
-
- g_return_val_if_fail (ptr != NULL, NULL);
-
- new_pos = _gtk_sequence_node_get_pos (ptr) + delta;
-
- return _gtk_sequence_node_find_by_pos (ptr, new_pos);
-}
-
-void
-_gtk_sequence_sort_changed (GtkSequencePtr ptr,
- GCompareDataFunc cmp_func,
- gpointer cmp_data)
-
-{
- GtkSequence *seq;
-
- g_return_if_fail (ptr != NULL);
- g_return_if_fail (!ptr->is_end);
-
- seq = _gtk_sequence_node_get_sequence (ptr);
- _gtk_sequence_unlink (seq, ptr);
- _gtk_sequence_node_insert_sorted (seq->node, ptr, cmp_func, cmp_data);
-}
-
-/* search
- *
- * The only restriction on the search function is that it
- * must not delete any nodes. It is permitted to insert new nodes,
- * but the caller should "know what he is doing"
- */
-void
-_gtk_sequence_search (GtkSequence *seq,
- GtkSequenceSearchFunc f,
- gpointer data)
-{
- GQueue *intervals = g_queue_new ();
-
- g_queue_push_tail (intervals, _gtk_sequence_node_find_first (seq->node));
- g_queue_push_tail (intervals, _gtk_sequence_node_find_last (seq->node));
-
- while (!g_queue_is_empty (intervals))
- {
- GtkSequenceNode *begin = g_queue_pop_head (intervals);
- GtkSequenceNode *end = g_queue_pop_head (intervals);
-
- if (f (begin, end, data))
- {
- gint begin_pos = _gtk_sequence_node_get_pos (begin);
- gint end_pos = _gtk_sequence_node_get_pos (end);
-
- if (end_pos - begin_pos > 1)
- {
- GtkSequenceNode *mid;
- gint mid_pos;
-
- mid_pos = begin_pos + (end_pos - begin_pos) / 2;
- mid = _gtk_sequence_node_find_by_pos (begin, mid_pos);
-
- g_queue_push_tail (intervals, begin);
- g_queue_push_tail (intervals, mid);
-
- g_queue_push_tail (intervals, mid);
- g_queue_push_tail (intervals, end);
- }
- }
- }
-
- g_queue_free (intervals);
-}
-
-#if 0
-/* aggregates */
-void
-_gtk_sequence_add_aggregate (GtkSequence *seq,
- const gchar *aggregate,
- GtkSequenceAggregateFunc f,
- gpointer data,
- GDestroyNotify destroy)
-{
- /* FIXME */
-}
-
-void
-_gtk_sequence_remove_aggregate (GtkSequence *seq,
- const gchar aggregate)
-{
- /* FIXME */
-
-}
-
-void
-_gtk_sequence_set_aggregate_data (GtkSequencePtr ptr,
- const gchar *aggregate,
- gpointer data)
-{
- /* FIXME */
-
-}
-
-gpointer
-_gtk_sequence_get_aggregate_data (GtkSequencePtr begin,
- GtkSequencePtr end,
- const gchar *aggregate)
-{
- g_assert_not_reached();
- return NULL;
-}
-#endif
-
-
-/* Nodes
- */
-static void
-_gtk_sequence_node_update_fields (GtkSequenceNode *node)
-{
- g_assert (node != NULL);
-
- node->n_nodes = 1;
-
- if (node->left)
- node->n_nodes += node->left->n_nodes;
-
- if (node->right)
- node->n_nodes += node->right->n_nodes;
-
-#if 0
- if (node->left || node->right)
- g_assert (node->n_nodes > 1);
-#endif
-}
-
-#define NODE_LEFT_CHILD(n) (((n)->parent) && ((n)->parent->left) == (n))
-#define NODE_RIGHT_CHILD(n) (((n)->parent) && ((n)->parent->right) == (n))
-
-static void
-_gtk_sequence_node_rotate (GtkSequenceNode *node)
-{
- GtkSequenceNode *tmp, *old;
-
- g_assert (node->parent);
- g_assert (node->parent != node);
-
- if (NODE_LEFT_CHILD (node))
- {
- /* rotate right */
- tmp = node->right;
-
- node->right = node->parent;
- node->parent = node->parent->parent;
- if (node->parent)
- {
- if (node->parent->left == node->right)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
-
- g_assert (node->right);
-
- node->right->parent = node;
- node->right->left = tmp;
-
- if (node->right->left)
- node->right->left->parent = node->right;
-
- old = node->right;
- }
- else
- {
- /* rotate left */
- tmp = node->left;
-
- node->left = node->parent;
- node->parent = node->parent->parent;
- if (node->parent)
- {
- if (node->parent->right == node->left)
- node->parent->right = node;
- else
- node->parent->left = node;
- }
-
- g_assert (node->left);
-
- node->left->parent = node;
- node->left->right = tmp;
-
- if (node->left->right)
- node->left->right->parent = node->left;
-
- old = node->left;
- }
-
- _gtk_sequence_node_update_fields (old);
- _gtk_sequence_node_update_fields (node);
-}
-
-static GtkSequenceNode *
-splay (GtkSequenceNode *node)
-{
- while (node->parent)
- {
- if (!node->parent->parent)
- {
- /* zig */
- _gtk_sequence_node_rotate (node);
- }
- else if ((NODE_LEFT_CHILD (node) && NODE_LEFT_CHILD (node->parent)) ||
- (NODE_RIGHT_CHILD (node) && NODE_RIGHT_CHILD (node->parent)))
- {
- /* zig-zig */
- _gtk_sequence_node_rotate (node->parent);
- _gtk_sequence_node_rotate (node);
- }
- else
- {
- /* zig-zag */
- _gtk_sequence_node_rotate (node);
- _gtk_sequence_node_rotate (node);
- }
- }
-
- return node;
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_new (gpointer data)
-{
- GtkSequenceNode *node = g_new0 (GtkSequenceNode, 1);
-
- node->parent = NULL;
- node->left = NULL;
- node->right = NULL;
-
- node->data = data;
- node->is_end = FALSE;
- node->n_nodes = 1;
-
- return node;
-}
-
-static GtkSequenceNode *
-find_min (GtkSequenceNode *node)
-{
- splay (node);
-
- while (node->left)
- node = node->left;
-
- return node;
-}
-
-static GtkSequenceNode *
-find_max (GtkSequenceNode *node)
-{
- splay (node);
-
- while (node->right)
- node = node->right;
-
- return node;
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_find_first (GtkSequenceNode *node)
-{
- return splay (find_min (node));
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_find_last (GtkSequenceNode *node)
-{
- return splay (find_max (node));
-}
-
-static gint
-get_n_nodes (GtkSequenceNode *node)
-{
- if (node)
- return node->n_nodes;
- else
- return 0;
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_find_by_pos (GtkSequenceNode *node,
- gint pos)
-{
- gint i;
-
- g_assert (node != NULL);
-
- splay (node);
-
- while ((i = get_n_nodes (node->left)) != pos)
- {
- if (i < pos)
- {
- node = node->right;
- pos -= (i + 1);
- }
- else
- {
- node = node->left;
- g_assert (node->parent != NULL);
- }
- }
-
- return splay (node);
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_prev (GtkSequenceNode *node)
-{
- splay (node);
-
- if (node->left)
- {
- node = node->left;
- while (node->right)
- node = node->right;
- }
-
- return splay (node);
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_next (GtkSequenceNode *node)
-{
- splay (node);
-
- if (node->right)
- {
- node = node->right;
- while (node->left)
- node = node->left;
- }
-
- return splay (node);
-}
-
-static gint
-_gtk_sequence_node_get_pos (GtkSequenceNode *node)
-{
- splay (node);
-
- return get_n_nodes (node->left);
-}
-
-static GtkSequence *
-_gtk_sequence_node_get_sequence (GtkSequenceNode *node)
-{
- splay (node);
-
- return node->sequence;
-}
-
-static GtkSequenceNode *
-_gtk_sequence_node_find_closest (GtkSequenceNode *node,
- GtkSequenceNode *other,
- GCompareDataFunc cmp,
- gpointer data)
-{
- GtkSequenceNode *best;
- gint c;
-
- splay (node);
-
- do
- {
- best = node;
-
- if ((c = cmp (node, other, data)) != 0)
- {
- if (c < 0)
- node = node->right;
- else
- node = node->left;
- }
- }
- while (c != 0 && node != NULL);
-
- return best;
-}
-
-static void
-_gtk_sequence_node_free (GtkSequenceNode *node,
- GDestroyNotify destroy)
-{
- /* FIXME:
- *
- * This is to avoid excessively deep recursions. A splay tree is not necessarily
- * balanced at all.
- *
- * I _think_ this is still linear in the number of nodes, but I'd like to
- * do something more efficient.
- */
-
- while (node)
- {
- GtkSequenceNode *next;
-
- node = splay (find_min (node));
- next = node->right;
- if (next)
- next->parent = NULL;
-
- if (destroy && !node->is_end)
- destroy (node->data);
- g_free (node);
-
- node = next;
- }
-}
-
-#if 0
-static gboolean
-_gtk_sequence_node_is_singleton (GtkSequenceNode *node)
-{
- splay (node);
-
- if (node->left || node->right)
- return FALSE;
-
- return TRUE;
-}
-#endif
-
-static void
-_gtk_sequence_node_split (GtkSequenceNode *node,
- GtkSequenceNode **left,
- GtkSequenceNode **right)
-{
- GtkSequenceNode *left_tree;
-
- splay (node);
-
- left_tree = node->left;
- if (left_tree)
- {
- left_tree->parent = NULL;
- _gtk_sequence_node_update_fields (left_tree);
- }
-
- node->left = NULL;
- _gtk_sequence_node_update_fields (node);
-
- if (left)
- *left = left_tree;
-
- if (right)
- *right = node;
-}
-
-static void
-_gtk_sequence_node_insert_before (GtkSequenceNode *node,
- GtkSequenceNode *new)
-{
- g_assert (node != NULL);
- g_assert (new != NULL);
-
- splay (node);
-
- new = splay (find_min (new));
- g_assert (new->left == NULL);
-
- if (node->left)
- node->left->parent = new;
-
- new->left = node->left;
- new->parent = node;
-
- node->left = new;
-
- _gtk_sequence_node_update_fields (new);
- _gtk_sequence_node_update_fields (node);
-}
-
-static gint
-_gtk_sequence_node_get_length (GtkSequenceNode *node)
-{
- g_assert (node != NULL);
-
- splay (node);
- return node->n_nodes;
-}
-
-static void
-_gtk_sequence_node_remove (GtkSequenceNode *node)
-{
- GtkSequenceNode *right, *left;
-
- splay (node);
-
- left = node->left;
- right = node->right;
-
- node->left = node->right = NULL;
-
- if (right)
- {
- right->parent = NULL;
-
- right = _gtk_sequence_node_find_first (right);
- g_assert (right->left == NULL);
-
- right->left = left;
- if (left)
- {
- left->parent = right;
- _gtk_sequence_node_update_fields (right);
- }
- }
- else if (left)
- left->parent = NULL;
-}
-
-#if 0
-/* debug func */
-static gint
-_gtk_sequence_node_calc_height (GtkSequenceNode *node)
-{
- /* breadth first traversal */
- gint height = 0;
- GQueue *nodes = g_queue_new ();
-
- g_queue_push_tail (nodes, node);
-
- while (!g_queue_is_empty (nodes))
- {
- GQueue *tmp = g_queue_new ();
-
- height++;
- while (!g_queue_is_empty (nodes))
- {
- GtkSequenceNode *node = g_queue_pop_head (nodes);
- if (node->left)
- g_queue_push_tail (tmp, node->left);
- if (node->right)
- g_queue_push_tail (tmp, node->right);
- }
-
- g_queue_free (nodes);
-
- nodes = tmp;
- }
- g_queue_free (nodes);
-
- return height;
-}
-#endif
-
-static void
-_gtk_sequence_node_insert_sorted (GtkSequenceNode *node,
- GtkSequenceNode *new,
- GCompareDataFunc cmp_func,
- gpointer cmp_data)
-{
- SortInfo info;
- GtkSequenceNode *closest;
- info.cmp = cmp_func;
- info.data = cmp_data;
-
- closest =
- _gtk_sequence_node_find_closest (node, new, node_compare, &info);
-
- g_assert (closest != new);
-
- if (node_compare (new, closest, &info) > 0)
- closest = _gtk_sequence_node_next (closest);
-
- _gtk_sequence_node_insert_before (closest, new);
-}
-
-static gint
-_gtk_sequence_node_calc_height (GtkSequenceNode *node)
-{
- gint left_height;
- gint right_height;
-
- if (node)
- {
- left_height = 0;
- right_height = 0;
-
- if (node->left)
- left_height = _gtk_sequence_node_calc_height (node->left);
-
- if (node->right)
- right_height = _gtk_sequence_node_calc_height (node->right);
-
- return MAX (left_height, right_height) + 1;
- }
-
- return 0;
-}
-
-gint
-_gtk_sequence_calc_tree_height (GtkSequence *seq)
-{
- GtkSequenceNode *node = seq->node;
- gint r, l;
- while (node->parent)
- node = node->parent;
-
- if (node)
- {
- r = _gtk_sequence_node_calc_height (node->right);
- l = _gtk_sequence_node_calc_height (node->left);
-
- return MAX (r, l) + 1;
- }
- else
- return 0;
-}
-
-GtkSequence *
-_gtk_sequence_ptr_get_sequence (GtkSequencePtr ptr)
-{
- GtkSequenceNode *node = ptr;
-
- return node->sequence;
-}
-
-void
-_gtk_sequence_swap (GtkSequencePtr a,
- GtkSequencePtr b)
-{
- GtkSequenceNode *leftmost, *rightmost, *rightmost_next;
- int a_pos, b_pos;
-
- g_return_if_fail (!_gtk_sequence_ptr_is_end (a));
- g_return_if_fail (!_gtk_sequence_ptr_is_end (b));
-
- if (a == b)
- return;
-
- a_pos = _gtk_sequence_ptr_get_position (a);
- b_pos = _gtk_sequence_ptr_get_position (b);
-
- if (a_pos > b_pos)
- {
- leftmost = b;
- rightmost = a;
- }
- else
- {
- leftmost = a;
- rightmost = b;
- }
-
- rightmost_next = _gtk_sequence_node_next (rightmost);
-
- /* Situation now: ..., leftmost, ......., rightmost, rightmost_next, ... */
-
- _gtk_sequence_move (rightmost, leftmost);
- _gtk_sequence_move (leftmost, rightmost_next);
-}
-
-void
-_gtk_sequence_move (GtkSequencePtr ptr,
- GtkSequencePtr new_pos)
-{
- g_return_if_fail (ptr != NULL);
- g_return_if_fail (new_pos != NULL);
-
- if (ptr == new_pos)
- return;
-
- _gtk_sequence_unlink (ptr->sequence, ptr);
- _gtk_sequence_node_insert_before (new_pos, ptr);
-}
-
-/* Overwrites the existing pointer. */
-void
-_gtk_sequence_set (GtkSequencePtr ptr,
- gpointer data)
-{
- GtkSequence *seq;
-
- g_return_if_fail (!_gtk_sequence_ptr_is_end (ptr));
-
- seq = _gtk_sequence_node_get_sequence (ptr);
- if (seq->data_destroy_notify)
- seq->data_destroy_notify (ptr->data);
- ptr->data = data;
-}